/*
 * Copyright (c) 2010 Thomas Wolfe. All rights reserved.  Use of this
 * source code is governed by a Simplified BSD license that can be found in the
 * LICENSE file.
 */
/*
 * Regex Matches
 * 12/31/2002     | Dec 31, 2002 | December 31 2002 | 12-31-2002 | 2002/12/31 (ISO 8601) | 12/31/2002 20:00 | 12/31/2002 08:00 PM
 * Non-Matches
 * 12/31/02  | 15/12/2002 (day month year) | 2002/12/3 (needs a two digit day in this case to prevent breaking 2 digit day)
 */
var regex = /(((([0]?[1-9]|1[0-2])|(Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December))(\/|-|\.| |, )([0-2]?[0-9]|3[0-1])(\/|-|\.| |, )([1-2]\d{3}))|(([1-2]\d{3})(\/|-|\.| |, )(([0]?[1-9]|1[0-2])|(Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December))(\/|-|\.| |, )([0-2]?[0-9]|3[0-1]){2}))( (([0-1]?\d)|(2[0-3])):[0-5]\d)?( AM| am| PM| pm)?/ig;

// Removes duplicate values from an array
function unique(inputArray){
    var outputArray = new Array();
    o: for (var i = 0; i < inputArray.length; i++) {
        for (var x = 0; x < outputArray.length; x++) {
            if (outputArray[x] == inputArray[i]) 
                continue o;
        }
        outputArray[outputArray.length] = inputArray[i];
    }
    return outputArray;
}

// Converts the given time into UTC, returns this in a string
function getUTCDateString(y, m, d, h, min){
    var timeObj = new Date(y, m - 1, d, h, min);
    var dateStr = "" + timeObj.getUTCFullYear();
    dateStr += stringPad(timeObj.getUTCMonth() + 1);
    dateStr += stringPad(timeObj.getUTCDate());
    dateStr += "T" + stringPad(timeObj.getUTCHours());
    dateStr += stringPad(timeObj.getUTCMinutes()) + "00Z";
    return dateStr;
}

// Add a leading '0' if string is only 1 char
function stringPad(str){
    var newStr = "" + str;
    if (newStr.length == 1) {
        newStr = "0" + newStr;
    }
    return newStr;
}

function getMonthByName(str){
    var newStr = "" + str;
    var month;
    switch (newStr) {
        case "Jan":
        case "January":
            month = 1;
            break;
        case "Feb":
        case "February":
            month = 2;
            break;
        case "Mar":
        case "March":
            month = 3;
            break;
        case "Apr":
        case "April":
            month = 4;
            break;
        case "May":
            month = 5;
            break;
        case "Jun":
        case "June":
            month = 6;
            break;
        case "Jul":
        case "July":
            month = 7;
            break;
        case "Aug":
        case "August":
            month = 8;
            break;
        case "Sep":
        case "September":
            month = 9;
            break;
        case "Oct":
        case "October":
            month = 10;
            break;
        case "Nov":
        case "November":
            month = 11;
            break;
        default:
            month = 12;
    }
    return month;
}

function indiciesOfText(stringToSearch, searchFor)
{
	var regex = new RegExp(searchFor,"g"), result, indices = [];
	while ( (result = regex.exec(stringToSearch)) ) {
	    indices.push(result.index+searchFor.length);
	}
	return indices;
}
function createLinkImg(dateStr)
{
	var dateImg = document.createElement("IMG");
	dateImg.title = "Add this event to your Google Calendar";
	dateImg.src = chrome.extension.getURL("Config-date-16.png")
	var dateLink = document.createElement("A");
	dateLink.target = "_blank";
	dateLink.href = "http://www.google.com/calendar/event?action=TEMPLATE&text=someevent&dates=" + dateStr + "&details=&location=&trp=false&sprop=&sprop=";
	dateLink.appendChild(dateImg);
	return dateLink;
}
function replaceText(dateStr, dateTxt, tobeReplacedNode) {
	dateLink = createLinkImg(dateStr);
	// if textNode search and replace
	if (tobeReplacedNode.nodeType == 3) {
		if (tobeReplacedNode.textContent.search(new RegExp(dateTxt,"g")) != -1) {
			var splitTxtNode = indiciesOfText(tobeReplacedNode.textContent,dateTxt);
			for (var k = 0; k < splitTxtNode.length; k++) {
				if (k == 0) {
					var txtAfterOffsetNode = tobeReplacedNode.splitText(splitTxtNode[k]);
					tobeReplacedNode.parentNode.insertBefore(dateLink, tobeReplacedNode.nextSibling);
				}
				else {
					var txtAfterOffsetNode = txtAfterOffsetNode.splitText(splitTxtNode[k]-splitTxtNode[k-1]);
					txtAfterOffsetNode.parentNode.insertBefore(dateLink, txtAfterOffsetNode.nextSibling);
				}
			}
		}
	}
	if (tobeReplacedNode.hasChildNodes() && splitTxtNode == null) {
		//recall this function
		for (var j = 0; j < tobeReplacedNode.childNodes.length; j++) {
			replaceText(dateStr, dateTxt, tobeReplacedNode.childNodes[j]);
		}
	}
	//return tobeReplacedNode;
}
function getMonthDayYearHourMin(date) {
	var arraySplits = date.split(/(\/|-|\.| |, |:)/gi);
	
	// set time (hour/min)
	if (arraySplits.length > 5) {
		hour = arraySplits[6];
		min = arraySplits[8];
		if (arraySplits.length > 9) {
			ampm = arraySplits[10];
			if (ampm == "pm" | "PM") {
				hour = 12 + parseInt(hour);
				hour = hour.toString();
			}
		}
	}
	else // no time provided, set to 00:00
	{
		hour = "00";
		min = "00";
	}
	// if the year is not the first element day/year/month are in different locations
	if (arraySplits[0].length != 4 | (arraySplits[0] == "June" | "July")) {
		year = arraySplits[4];
		
		if (parseInt(arraySplits[0]) > 12) {
			if (arraySplits[2].length < 3) {
				month = arraySplits[2];
			}
			else {
				month = getMonthByName(arraySplits[2]);
			}
			day = arraySplits[0];
		}
		if (arraySplits[0].length < 3) {
			month = arraySplits[0];
		}
		else {
			month = getMonthByName(arraySplits[0]);
		}
		day = arraySplits[2];
	}
	else {
		year = arraySplits[0];
		if (parseInt(arraySplits[2]) > 12) {
			day = arraySplits[2];
			month = arraySplits[4];
		}
		else {
			month = arraySplits[2];
			day = arraySplits[4];
		}
	}
	return getUTCDateString(year, month, day, hour, min);
}
function replaceBody(date, bodyElement) {
	initDateString = getMonthDayYearHourMin(date);
    dateString = initDateString + "/" + initDateString;
					
	replaceText(dateString, date, bodyElement);
    //oldBody = document.replaceChild(bodyElement,document.body);
}

// Test the text of the body element against our regular expression.
if (regex.test(document.body.innerText)) {
    // The regular expression produced a match, so notify the background page.
    chrome.extension.sendRequest({}, function(response){
    });
    var bodyElement = document.getElementsByTagName("BODY")[0];
    var nonUniqueArrayDates = document.body.innerText.match(regex); // array of date/time values
    var arrayDates = unique(nonUniqueArrayDates);
	
	// FIXME: ugly hack for this for loop to deal with issue 9 which I cannot figure out
	for (var i = 0; i < Math.min(arrayDates.length,20); i++) {
		replaceBody(arrayDates[i], bodyElement);
	}
}
else {
    // No match was found.
}
